home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 02 - 1986 / 02.06 Jun 86.sit / 02.06 Jun 86 / Pascal source / vidstuff.asm / vidstuff.asm
Encoding:
Assembly Source File  |  1986-05-06  |  7.0 KB  |  167 lines  |  [TEXT/EDIT]

  1. ; vid -- Routines to synchronize switching between the two hardware screens
  2. ; in sync with the screen refresh, allowing smooth animation.
  3. ;       mike morton, may 1986
  4.  
  5. ; function  vidwait    (VAR block: vidinfo): longint;           external;
  6. ; procedure vidstart   (VAR block: vidinfo; period: integer);  external;
  7. ; procedure getaltscreen;                       external;
  8.  
  9. ; MDS ASSEMBLER VERSION
  10. ; Converted by David E. Smith for MacTutor.
  11. ;
  12. ;
  13.     xdef    vidwait
  14.     xdef    vidstart
  15.     xdef    getaltscreen
  16.     
  17.     Include QuickEqu.D    ; MDS toolbox equates and traps
  18.     Include SysEqu.D
  19.     Include ToolEqu.D
  20.     Include MacTraps.D
  21.  
  22.     MACRO .equ = equ|    ; convert Lisa assembler stuff to MDS Mac
  23.     MACRO _hidecurs = _HideCursor|
  24.     MACRO _showcurs = _ShowCursor|
  25.     
  26. ; definition of state information record.  *** also defined on Pascal side. ***
  27.  
  28. vblsize .equ    vblphase+2      ; size of VBL block
  29.  
  30. ivbl    .equ    0            ; VBL task information
  31. ireq    .equ    ivbl+vblsize    ; (integer) request: alt/default/stop/none
  32. iperiod .equ    ireq+2            ; (integer) default period in ticks
  33. idelays .equ    iperiod+2       ; (longint) number of times we've had to delay for a tick
  34.  
  35. isize   .equ    idelays+4       ; size of “info” block
  36.  
  37. viabase    .equ    $1D4    ;$1D4 VIA base address global (VIA)
  38. CurPage    .equ    $936    ;$936 alternate screen page status global (CurPageOption)
  39.  
  40. ;
  41. ; request definitions: the high level code saves these for us to see.
  42. ; *** note: the code at “vbl” depends on these values. ***
  43. ;
  44. reqalt  .equ    0                ; request switch to alternate screen
  45. reqdef  .equ    1                ; request switch to default screen
  46. reqstop .equ    2                ; stop on default screen
  47. reqnone .equ    3                ; nothing requested
  48.  
  49. ; ----------------------------------------------------------------------------
  50.  
  51. ;
  52. ; function vidwait (block: ptr): longint; external;
  53. ; this routine is called when the next animation frame is ready to be shown
  54. ; and the main program has made a request to display that frame.  it waits
  55. ; until the new frame is being shown, then returns.  it also returns the
  56. ; approximate time it had to wait, in arbitrary units.  this helps you find
  57. ; out how much slack you have between the time the frame is ready and the time
  58. ; it's actually used.
  59.  
  60. vidwait:
  61.         move.l  (SP)+,A1            ; pop return
  62.         move.l  (SP)+,A0            ; pop block pointer
  63.         moveq   #-1,D0                ; will be 0 if we exit right away
  64.  
  65. vidw2:  addq.l  #1,D0                ; bump spinning counter
  66.         cmp.w   #reqnone,ireq(A0)       ; is nothing waiting to happen?
  67.         bne.s   vidw2                ; something pending: don't return yet
  68.  
  69.         move.l  D0,(SP)                ; return “time” waited
  70.         jmp     (A1)                ; return
  71.  
  72. ; ----------------------------------------------------------------------------
  73.  
  74. ;
  75. ; procedure vidstart (block: ptr; period: integer); external;
  76. ;
  77.  
  78. vidstart:
  79.         move.l  6(SP),A0            ; point to VBL block (also info block)
  80.         move.w  4(SP),D0            ; pick up desired period
  81.  
  82.         move.w  #reqnone,ireq(A0)       ; initialize request info to “none”
  83.         move.w  D0,iperiod(A0)            ; save period
  84.         clr.l   idelays(A0)            ; no delays seen yet
  85.  
  86.         move.w  #vType,vblType(A0)      ; set the type of queue element
  87.         lea     vbl,A1                ; point to VBL routine to call
  88.         move.l  A1,vblAddr(A0)            ; save the address of the routine
  89.         move.w  D0,vblCount(A0)            ; set time to wait for the first call
  90.         clr.w   vblPhase(A0)            ; zero phase -- do I need to do this?
  91.  
  92.         _vInstall                ; install the vertical retrace task
  93.         tst.w   D0                ; good status?
  94.         bne.s   death                ; no: bag it
  95.  
  96. @1      move.l  (SP)+,A0            ; pop return
  97.         addq.l  #4+2,SP                ; ding one long, one integer parameter
  98.         jmp     (A0)                ; and return with the task queued
  99.  
  100. ; ----------------------------------------------------------------------------
  101.  
  102. ; this is our entry point from the vertical retrace manager.
  103. ; entered by: A0 points to VBL block; our state information follows this.
  104. ;
  105. ; - if no request has been made by the time we're called, the main program
  106. ;   didn't have a frame to be drawn in time; in this case, we increment the
  107. ;   “delays” counter and set the alarm to wake us up one tick from now.
  108. ; - if a request is there, we do it and set the alarm for one full period.
  109.  
  110. vbl:    move.w  ireq(A0),D0            ; pick up the request
  111.         move.w  #reqnone,ireq(A0)       ; cancel any pending request
  112.         move.l  viabase,A1                ; point to base of VIA stuff
  113.  
  114.         dbra    D0,vbl1                ; skip if not zero
  115.         bclr    #6,$1E00(A1)            ; alternate screen: clear the bit
  116.         move.w  iperiod(A0),vblCount(A0) ; ask for next wake-up at usual time
  117.         rts                    ; exit
  118.  
  119. vbl1:   dbra    D0,vbl2                ; wasn't zero; skip if not one
  120.         bset    #6,$1E00(A1)            ; default screen: set the bit
  121.         move.w  iperiod(A0),vblCount(A0) ; ask for next wake-up at usual time
  122.         rts                    ; ta da
  123.  
  124. vbl2:   dbra    D0,vbl3                ; wasn't zero or one; skip if not two
  125.         clr.w   vblCount(A0)            ; stop: we don't want to run again
  126.         bset    #6,$1E00(A1)            ; default screen (make finder happy)
  127.         rts                    ; home for the last time
  128.  
  129. vbl3:   dbra    D0,death            ; wasn't 0,1, or 2; die if not three
  130.         move.w  #1,vblCount(A0)            ; no request: re-run in just one tick
  131.         add.l   #1,idelays(A0)            ; keep stats on how often this happens
  132.         rts                    ; and return
  133.  
  134. death:  DC.L   $60FE                ; execute an “ILLEGAL” instruction
  135.  
  136. ; ----------------------------------------------------------------------------
  137.  
  138. ; procedure getaltscreen; external;
  139. ; this should be the VERY first thing your application calls.
  140. ; - if the alternate video screen IS configured, we return and do nothing.
  141. ; - if the screen isn't there, we find out the application's name from the
  142. ;   application parameters and relaunch ourselves, correctly configured.
  143.  
  144.  
  145. getaltscreen:
  146.         tst.l   CurPage            ; pick up current screen configuration
  147.         bpl.s   relaunch            ; negative means we got alt. screen
  148.         rts                    ; all's well; return
  149.  
  150. relaunch:                    ; here when we have to restart
  151.         sub.l   #32+4+2,SP            ; room for apName, apRefNum, apParam
  152.         move.l  SP,A0                ; point to base of this stuff
  153.         pea     4+2(A0)                ; push arg1: VAR pointer to apName
  154.         pea     4(A0)                ; push arg2: VAR pointer to apRefNum
  155.         pea     0(A0)                ; push arg3: VAR pointer to apParam
  156.         _GetAppParms                ; fill in name, other junk; pop params
  157.  
  158.         ; Now apParam, apRefNum and (importantly) apName are in stack temps.
  159.         lea     4+2(SP),A0            ; point to the name we just got
  160.         move.l  #-1,-(SP)            ; -1 asks for alternate screen...
  161.         move.l  A0,-(SP)            ; ...and point to name to launch
  162.         move.l  SP,A0                ; point to name ptr and flags with A0
  163.         _launch                    ; launch ourselves, with alt screen
  164.         bra.s   death                ; shouldn't reach here!
  165.  
  166. end
  167.